package com.gs.cd.service.resource.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.binding.Binder;
import com.gs.cd.model.resource.SysResource;
import com.gs.cd.model.resource.SysResourceGroup;
import com.gs.cd.model.resource.SysResourceGroupOwnResource;
import com.gs.cd.model.resource.vo.SysResourceGroupOwnResourceVo;
import com.gs.cd.service.resource.mapper.SysResourceGroupMapper;
import com.gs.cd.service.resource.service.SysResourceGroupOwnResourceService;
import com.gs.cd.service.resource.service.SysResourceGroupService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author seven
 * @since 2020-12-22
 */
@Service
public class SysResourceGroupServiceImpl extends ServiceImpl<SysResourceGroupMapper, SysResourceGroup> implements SysResourceGroupService {
    /**
     * 获取非子资源组 资源组
     *
     * @param saleCode
     * @return
     */
    @Override
    public List<SysResourceGroup> listRoot(String saleCode) {
        return Binder.convertAndBindRelations(list(new QueryWrapper<SysResourceGroup>().lambda()
                .eq(SysResourceGroup::getSaleCode, saleCode).isNull(SysResourceGroup::getParentId)), SysResourceGroup.class)
                ;
    }

    /**
     * 通过saleCode 获取资源组
     *
     * @param saleCode
     * @return
     */
    @Override
    public List<SysResourceGroup> listBySaleCode(String saleCode) {
        return list(new QueryWrapper<SysResourceGroup>().lambda()
                .eq(SysResourceGroup::getSaleCode, saleCode));
    }

    /**
     * 通过saleCode 获取资源组
     *
     * @param saleCode
     * @param queryWrapper
     * @return
     */
    @Override
    public List<SysResourceGroup> listBySaleCode(String saleCode, QueryWrapper<SysResourceGroup> queryWrapper) {
        queryWrapper.lambda().eq(SysResourceGroup::getSaleCode, saleCode);
        return list(queryWrapper);
    }

    @Autowired
    private SysResourceGroupOwnResourceService sysResourceGroupOwnResourceService;

    /**
     * 通过ids获取资源组 携带资源 ids 为空表示查询所有
     *
     * @param saleCode
     * @param ids
     * @return todo 感觉用法不对，查询sql可能会很慢。。
     */
    @Override
    public List<SysResourceGroup> listWithResourceByIds(String saleCode, List<String> ids) {
        List<SysResourceGroup> sysResourceGroups = null;
        if (ids.isEmpty()) {
            sysResourceGroups = listBySaleCode(saleCode);
        } else {
            sysResourceGroups = listByIds(ids);
        }
        sysResourceGroups.forEach(sysResourceGroup -> {
            List<SysResourceGroupOwnResource> list = sysResourceGroupOwnResourceService.
                    listByResourceGroupCode(saleCode, sysResourceGroup.getCode());
            List<SysResourceGroupOwnResourceVo> sysResourceGroupOwnResourceVos = Binder.convertAndBindRelations(list, SysResourceGroupOwnResourceVo.class);
            ArrayList<SysResource> sysResources = new ArrayList<>();
            sysResourceGroupOwnResourceVos.forEach(sysResourceGroupOwnResourceVo -> {
                //移除非根资源
                if(sysResourceGroupOwnResourceVo.getSysResource()!=null){
                    if (sysResourceGroupOwnResourceVo.getSysResource().getParentId() == null) {
                        sysResources.add(sysResourceGroupOwnResourceVo.getSysResource());
                    }
                }
            });
            sysResourceGroup.setSysResourceList(sysResources);
        });
        return sysResourceGroups;
    }

    /**
     * 通过codes获取资源组
     *
     * @param saleCode
     * @param codes
     * @return
     */
    @Override
    public List<SysResourceGroup> listByCodes(String saleCode, List<String> codes) {
        if (codes.isEmpty()) {
            return new ArrayList<>();
        }
        return list(new QueryWrapper<SysResourceGroup>().lambda()
                .eq(SysResourceGroup::getSaleCode, saleCode).in(SysResourceGroup::getCode, codes));
    }

    /**
     * 通过code获取资源组
     *
     * @param saleCode
     * @param code
     * @return
     */
    @Override
    public SysResourceGroup listByCode(String saleCode, String code) {
        return getOne(new QueryWrapper<SysResourceGroup>().lambda()
                .eq(SysResourceGroup::getSaleCode, saleCode).eq(SysResourceGroup::getCode, code));
    }

    /**
     * 通过saleCode删除 (并删除关联信息)
     *
     * @param saleCode
     * @return
     */
    @Override
    public boolean removeAndRelationsBySaleCode(String saleCode) {
        List<SysResourceGroup> list = listBySaleCode(saleCode);
        Set<String> collect = list.stream().map(SysResourceGroup::getCode).collect(Collectors.toSet());
        //删除关联资源
        boolean b1 = sysResourceGroupOwnResourceService.removeByResourceGroupCodes(saleCode, collect);
        //删除资源组
        boolean b = removeByIds(list.stream().map(SysResourceGroup::getId).collect(Collectors.toSet()));
        return b;
    }

    @Override
    public boolean copy(String currentSaleCode, String targetSaleCode) {
        //1. 查询当前资源组
        List<SysResourceGroup> list = listBySaleCode(currentSaleCode);
        Set<String> collect = list.stream().map(SysResourceGroup::getCode).collect(Collectors.toSet());
        //2. 查询关联资源
        List<SysResourceGroupOwnResource> sysResourceGroupOwnResources = sysResourceGroupOwnResourceService.
                listByResourceGroupCodes(currentSaleCode, collect);
        //3. 删除target资源组
        removeAndRelationsBySaleCode(targetSaleCode);
        //4. 调整数据 并存储
        list.forEach(s -> {
            s.setId(StrUtil.removeSuffix(s.getId(), currentSaleCode) + targetSaleCode);
            s.setParentId(s.getParentId() == null ? null : StrUtil.removeSuffix(s.getParentId(), currentSaleCode) + targetSaleCode);
            s.setSaleCode(targetSaleCode);
        });
        int i = getBaseMapper().insertBatchNotAuto(list);
        sysResourceGroupOwnResources.forEach(s -> s.setSysSaleCode(targetSaleCode));
        boolean b = sysResourceGroupOwnResourceService.saveBatch(sysResourceGroupOwnResources);
        return b;
    }

    @Override
    public boolean drag(List<String> ids) {
        Collection<SysResourceGroup> sysResourceGroups = listByIds(ids);
        Map<String, SysResourceGroup> collect = sysResourceGroups.stream().collect(Collectors.toMap(SysResourceGroup::getId, s -> s));
        for (int i = 0; i < ids.size(); i++) {
            collect.get(ids.get(i)).setSort(i);
        }
        return updateBatchById(collect.values());
    }

    @Override
    public List<SysResourceGroup> listOnlyRoot(String saleCode) {
        return list(new QueryWrapper<SysResourceGroup>().lambda()
                .eq(SysResourceGroup::getSaleCode, saleCode)
                .isNull(SysResourceGroup::getParentId));
    }
}
